package com.zzyl.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.zzyl.base.ResponseResult;
import com.zzyl.constant.Constants;
import com.zzyl.constant.SuperConstant;
import com.zzyl.constant.UserCacheConstant;
import com.zzyl.dto.LoginDto;
import com.zzyl.entity.Resource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.SysUsersMapper;
import com.zzyl.properties.JwtTokenManagerProperties;
import com.zzyl.properties.SecurityConfigProperties;
import com.zzyl.service.LoginService;
import com.zzyl.service.ResourceService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private SysUsersMapper userMapper;
    @Autowired
    private JwtTokenManagerProperties jwtProperties;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private SecurityConfigProperties securityConfigProperties;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public UserVo login(LoginDto loginDto) {
        UserVo userVo = userMapper.selectByName(loginDto.getUsername());
        //验证用户是否存在
        if(Objects.isNull(userVo)){
            throw new BaseException(BasicEnum.DATA_NOT_EXIST);
        }
        //验证用户状态是否禁用
        if(Objects.equals(userVo.getDataState(), SuperConstant.DATA_STATE_1)){
            throw new BaseException(BasicEnum.USER_IS_FORBID);
        }
        //验证密码
        if(!BCrypt.checkpw(loginDto.getPassword(),userVo.getPassword())){
            throw new BaseException(BasicEnum.USER_POSSWORD_ERROR);
        }

        //获取白名单
        List<String> publicAccessUrls = securityConfigProperties.getPublicAccessUrls();
        //获取用户拥有的资源
        List<Resource> reservationList = resourceService.getAllResourceById(userVo.getId());
        //去重
        //Set<String> urlSet = new HashSet<>();
//        if(!CollectionUtils.isEmpty(reservationList)){
//            Set<String> requestPathList = reservationList.stream().map(Resource::getRequestPath).collect(Collectors.toSet());
//            urlSet.addAll(requestPathList);
//        }
//        if(!CollectionUtils.isEmpty(publicAccessUrls)){
//            urlSet.addAll(publicAccessUrls);
//        }
        //去重
        Set<String> labrlSet = new HashSet<>();
        //获取白名单所对应的资源label
        List<String> reservationLableList = resourceService.getAllResourceLabelByPath(publicAccessUrls);
        //获取用户拥有的资源
        List<Resource> reservationLists = resourceService.getAllResourceById(userVo.getId());
        //拿到label字段
        if(!CollectionUtils.isEmpty(reservationLists)){
            Set<String> collect = reservationLists.stream().map(Resource::getLabel).collect(Collectors.toSet());
            labrlSet.addAll(collect);
        }
        if(!CollectionUtils.isEmpty(reservationLableList)){
            labrlSet.addAll(reservationLableList);
        }

        //放入redis
        //stringRedisTemplate.opsForSet().add(UserCacheConstant.USER_RESOURCE_LIST+userVo.getId(),urlSet.toArray(new String[0]));
        //过滤掉空值
        stringRedisTemplate.opsForSet().add(UserCacheConstant.USER_RESOURCE_LIST+userVo.getId(), labrlSet.stream().filter(Objects::nonNull).distinct().toArray(String[]::new));
        //验证通过生产token返回
        Map<String,Object> map = new HashMap<>();
        map.put(Constants.JWT_USERID,userVo.getId());
        map.put(Constants.JWT_USERNAME,userVo.getUsername());
        userVo.setUserToken(JwtUtil.createJWT(jwtProperties.getBase64EncodedSecretKey(), jwtProperties.getTtl(),map));
        userVo.setPassword("");
        return userVo;
    }
}
